package com.quwan.component;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.quwan.app.vo.InteractiveMsgParams;
import com.quwan.app.vo.PushOfflineMsgParams;
import com.quwan.common.ImMsgType;
import com.quwan.common.enums.DeviceEnum;
import com.quwan.common.enums.MemberStatusEnum;
import com.quwan.common.enums.StatusEnum;
import com.quwan.common.form.PushForm;
import com.quwan.common.result.PushDTO;
import com.quwan.common.result.TNPSResult;
import com.quwan.common.service.PushService;
import com.quwan.common.service.impl.tnps.AndroidTNPSMessage;
import com.quwan.common.service.impl.tnps.IosTNPSMessage;
import com.quwan.common.service.impl.tnps.TNPSPush;
import com.quwan.common.service.push.AbstractMessage;
import com.quwan.common.service.push.MsgSender;
import com.quwan.config.yml.ImConfig;
import com.quwan.constans.AppConst;
import com.quwan.entity.*;
import com.quwan.mapper.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author quan
 * @date 2021-11-03 15:10
 */
@Slf4j
@Component
@RequiredArgsConstructor
@Async("asyncThread")
public class AsyncTaskComponent {
    private final TPublishOrderMapper publishOrderMapper;
    private final TMemberLevelMapper memberLevelMapper;
    private final TMemberMapper memberMapper;
    private final TLoginRecordMapper loginRecordMapper;
    private final TMessageMapper messageMapper;
    private final PushService pushService;
    private final TencentComponent tencentComponent;
    private final TSystemPushMsgMapper systemPushMsgMapper;

    /**
     * 推送用户离线消息
     *
     * @param params 接收者用户 信息
     */
    public void pushOfflineMsgToMember(PushOfflineMsgParams params) {
        String title = params.getTitle();
        String content = params.getContent();
        Long mId = params.getMId();
        TMember member = memberMapper.selectOne(
                new LambdaQueryWrapper<TMember>()
                        .select(TMember::getSource)
                        .eq(TMember::getId, mId)
                        .eq(TMember::getStatus, MemberStatusEnum.NORMAL.getCode())
        );
        if (member == null) return;

        TMessage message =
                new TMessage()
                        .setUserId(mId)
                        .setBody(content)
                        .setTitle(title)
                        .setStatus(params.getStatus())
                        .setType(params.getType());
        Map<String, String> map = params.getMap();
        PushForm form = new PushForm(title, content, String.valueOf(mId), map);
        PushDTO res = null;
        if (DeviceEnum.ANDROID.getType().equals(member.getSource())) {
            res = pushService.pushAndroid(form);
            message.setMessageId(res.getPushId()).setPlatform(DeviceEnum.ANDROID.getType().byteValue());
            log.info("android:msg end::{}", JSONObject.toJSONString(res));
        } else if (DeviceEnum.IOS.getType().equals(member.getSource())) {
            res = pushService.pushIos(form);
            message.setMessageId(res.getPushId()).setPlatform(DeviceEnum.IOS.getType().byteValue());
            log.info("IOS msg end::{}", JSONObject.toJSONString(res));
        } else {
            log.info("pushBuyItOrderMsg:fail OS notFound  targetMember::{}", mId);
            return;
        }
        if (res.getCode().equals(StatusEnum.SUCEESS.getCode()))
            messageMapper.insert(message);
        else
            log.info("离线推送失败:{}", JSONObject.toJSONString(res));

    }


    /**
     * 检查 会员等级是否满足更新
     *
     * @param mId
     */
    public void checkMemberLevel(String mId) {
        TMember member = memberMapper
                .selectOne(
                        new LambdaQueryWrapper<TMember>()
                                .select(
                                        TMember::getServiceLevel)
                                .eq(TMember::getId, mId)

                );
        if (member == null)
            return;
        Integer sum = publishOrderMapper.selectMemberSellCount(mId);
        if (sum == null || sum == 0)
            return;
        Map<Integer, Integer> level = memberLevelMapper
                .selectList(
                        new LambdaQueryWrapper<TMemberLevel>()
                                .select(TMemberLevel::getMaxConfition, TMemberLevel::getMLevel)

                )
                .stream()
                .collect(Collectors.toMap(TMemberLevel::getMLevel, TMemberLevel::getMaxConfition, (k1, k2) -> k1));
        Integer currLevel = member.getServiceLevel();
        if (currLevel == 0 && sum > 0)
            currLevel = 1;
        else {
            Integer condition = level.get(currLevel);
            if (sum > condition)
                currLevel = currLevel + 1;
            else
                return;
        }

        int memberRow =
                memberMapper
                        .update(null,
                                new LambdaUpdateWrapper<TMember>()
                                        .set(TMember::getServiceLevel, currLevel)
                                        .eq(TMember::getId, mId)
                        );
        if (memberRow != 1)
            log.warn("update member level fail level::{}", currLevel);

    }


    /**
     * 发单 订单取消次数
     *
     * @param publishOrderId
     */
    public void updPublishCancelCount(String publishOrderId) {
        TPublishOrder publishOrder = publishOrderMapper.selectOne(
                new LambdaQueryWrapper<TPublishOrder>()
                        .select(TPublishOrder::getCancelCount)
                        .eq(TPublishOrder::getId, publishOrderId)
        );
        if (publishOrder == null) return;

        int row =
                publishOrderMapper
                        .update(
                                null,
                                new LambdaUpdateWrapper<TPublishOrder>()
                                        .set(TPublishOrder::getCancelCount, publishOrder.getCancelCount() + 1)
                                        .eq(TPublishOrder::getId, publishOrderId)
                                        .eq(TPublishOrder::getCancelCount, publishOrder.getCancelCount())
                        );
        if (row != 1)
            log.error("修改取消订单数量失败::publishOrderId:{}", publishOrderId);
    }

    /**
     * 登录记录保存
     *
     * @param mId
     * @param type
     * @param source 不为空 更新一下会员 操作系统
     */
    public void addLoginRecord(Long mId, Integer type, String source) {
        if (StringUtils.isNotBlank(source))
            memberMapper.update(null,
                    new LambdaUpdateWrapper<TMember>()
                            .set(TMember::getSource, source)
                            .eq(TMember::getId, mId));
        if (loginRecordMapper.insert(
                new TLoginRecord()
                        .setMId(mId)
                        .setLoginStatus(type)
        )
                != 1)
            log.info("addLoginRecord fail mId::{},type::{}", mId, type);


    }

    /**
     * 互动消息 推送
     * @param params
     */
    public void pushInteractiveMsg(InteractiveMsgParams params) {
        Boolean success = tencentComponent.singlePushMsg(2, params.getFromAcc(), params.getFromAcc(), params.getToAcc(), ImMsgType.text.getCode(), params.getContent());
        if (success) {
            systemPushMsgMapper.insert(
                    new TSystemPushMsg()
                            .setType(Math.abs(params.getType()))
                            .setReceiverId(params.getToAcc())
                            .setContent(JSONObject.toJSONString(params.setContent(null).setFromAcc(null).setToAcc(null)))
                            .setCreateBy("system")

            );
        }

    }
}